Skip to content

Fix plugin calls crashing on iOS: depend on WasmKit with wasmkit_tc_start in C - #25

Merged
colemancda merged 2 commits into
masterfrom
fix/wasmkit-direct-threaded
Nov 4, 2026
Merged

colemancda merged 2 commits into
masterfrom
fix/wasmkit-direct-threaded

Conversation

@colemancda

Copy link
Copy Markdown
Member

Every call into a plugin crashes in optimized builds on iOS. This moves the app to a WasmKit fork commit that fixes it.

The crash

WasmKit runs Wasm with direct-threaded handlers that use the swiftasync calling convention. Those handlers overwrite its context register (x22 on arm64) and don't preserve it. The handlers are started by wasmkit_tc_start, a static inline C function in _CWasmKit.h. Once that function was inlined into Execution.runDirectThreaded, the call was treated as if it kept x22. After the handlers returned, the code read the execution's trap through the stale register. It took a value off the Wasm stack (an i32 result such as 42) as the error and crashed retaining it in swift_errorRetain.

That path runs only when memory bounds are checked in software, which is the default on iOS. macOS uses mprotect guards and goes through wasmkit_trap_guard_run, a real C function that saves the registers. So the crash didn't show on the Mac.

The fix

WasmKit fork, branch fix/direct-threaded-start (80990b7): wasmkit_tc_start is declared in the header and defined in _CWasmKit.c. As an ordinary C function it saves and restores its callee-saved registers around the handlers.

This PR only bumps the pin in Package.swift and Package.resolved.

Testing

A minimal module with (func (result i32) i32.const 42) and (func unreachable), run in a release build:

  • macOS with memoryBoundsChecking: .software: crashes before the fix; returns 42 and reports Trap: unreachable after it.
  • The iOS build: the same, before and after.

@colemancda
colemancda merged commit 2c658ba into master Nov 4, 2026
1 of 2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant